﻿using Inaction.Core;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;

namespace Inaction.Business
{
    [Serializable]
    public partial class EntityList<T, Detail> :
#if WPF
 System.Collections.ObjectModel.ObservableCollection<Detail>
#else
 System.ComponentModel.BindingList<Detail>
#endif
        where T : EntityList<T, Detail>, new()
        where Detail : Entity<Detail>, new()
    {
        public EntityList()
        {
            if (AppConfig.Instance.RunLocation == RunLocation.Client)
            {
                Key = GetHashCode();
            }
        }

        #region 属性
        protected IEnumerable<Detail> DeletedList { get { return DeletedEntites.Select(p => p.Entity); } }

        Stack<TrackEntity<Detail>> deletedEntities = new Stack<TrackEntity<Detail>>();
        private Stack<TrackEntity<Detail>> DeletedEntites
        {
            get { return deletedEntities; }
            set { deletedEntities = value; }
        }

        #endregion

        #region 方法

        
#if WINDOWS
        protected override object AddNewCore()
        {
            var detail = Entity<Detail>.New();
            this.Add(detail);
            return detail;
        }
#endif
        protected override void RemoveItem(int index)
        {
            var item = this[index];
            base.RemoveItem(index);
            if (!item.IsNew)
            {
                deletedEntities.Push(new TrackEntity<Detail>(index, item));
                item.MarkDeleted();
            }
        }

        protected override void InsertItem(int index, Detail item)
        {
            base.InsertItem(index, item);
            item.List = this;
            item.Master = this.Master;
        }

        public void AddRange(IEnumerable<Detail> details)
        {
            foreach (var detail in details)
            {
                this.Add(detail);
            }
        }

        [Serializable]
        private class TrackEntity<T> where T : Entity<T>, new()
        {
            public int Index { get; set; }

            public T Entity { get; set; }

            public TrackEntity(int index, T entity)
            {
                Index = index;
                Entity = entity;
            }
        }
        private void ClearDeletedEntites()
        {
            foreach (IDeletable item in this)
            {
                item.ClearDeletedEntites();
            }
            this.DeletedEntites.Clear();
        }
        #endregion
    }
}